﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace KgUtils
{
    public static partial class StringExtension
    {
        /// <summary>
        /// Indique si une chaine est nulle ou vide
        /// </summary>
        /// <param name="s">la chaine à tester</param>
        /// <returns>true si la chaine est nulle ou vide, false sinon</returns>
        public static bool IsNullOrEmpty(this string s)
        {
            return String.IsNullOrEmpty(s);
        }

        /// <summary>
        /// Indique si une chaîne est nulle, vide ou composée uniquement d'espaces blancs.
        /// </summary>
        /// <param name="s">la chaine à tester</param>
        /// <returns>true si la chaine est nulle, vide ou composée uniquement d'espaces blancs, false sinon</returns>
        public static bool IsNullOrWhiteSpace(this string s)
        {
            return String.IsNullOrWhiteSpace(s);
        }

        /// <summary>
        /// Enlève les caractères diacritiques (accents, cédilles...) d'une chaine en les remplaçant par le
        /// caractère de base.
        /// </summary>
        /// <param name="s">La chaine dont on veut enlever les diacritiques</param>
        /// <returns>La chaine sans les diacritiques</returns>
        public static string RemoveDiacritics(this string s)
        {
            Guard.AssertNotNull(s, "s");

            string formD = s.Normalize(NormalizationForm.FormD);
            string noDiacriticsFormD = new string(
                formD.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                     .ToArray());
            string noDiacritics = noDiacriticsFormD.Normalize(NormalizationForm.FormC);
            return noDiacritics;
        }

        /// <summary>
        /// Formate la chaine avec les valeurs spécifiées, de la même façon que
        /// String.Format
        /// </summary>
        /// <param name="format">La chaine de format</param>
        /// <param name="args">les valeurs à utiliser</param>
        /// <returns>La chaine formatée</returns>
        public static string FormatWith(this string format, params object[] args)
        {
            return string.Format(format, args);
        }

        public static string SafeSubstring(this String currentString, int length)
        {
            if (currentString.IsNullOrEmpty())
                return String.Empty;
            if (currentString.Length <= length)
                return currentString;
            else
                return currentString.Substring(0, length);
        }

        /// <summary>
        /// Indique si source contient la chaine toCheck, en utilisant les paramètres de comparaison spécifiés
        /// </summary>
        /// <param name="source"></param>
        /// <param name="toCheck"></param>
        /// <param name="comp"></param>
        /// <returns></returns>
        public static bool Contains(this string source, string toCheck, StringComparison comp)
        {
            return source.IndexOf(toCheck, comp) >= 0;
        }

        /// <summary>
        /// Indique si source contient la chaine toCheck, en utilisant les options de comparaison spécifiées
        /// </summary>
        /// <param name="source"></param>
        /// <param name="toCheck"></param>
        /// <param name="comp"></param>
        /// <returns></returns>
        public static bool Contains(this string source, string toCheck, CompareOptions comp)
        {
            var myComp = CultureInfo.InvariantCulture.CompareInfo;
            return myComp.IndexOf(source, toCheck, comp) >= 0;
        }

        /// <summary>
        /// Indique si source contient la chaine toCheck, avec la possibilité d'ignorer la casse et les diacritiques
        /// </summary>
        /// <param name="source"></param>
        /// <param name="toCheck"></param>
        /// <param name="ignoreCaseAndDiacritics">Si True, ignore la casse et les diacritiques, sinon effectue un Contains "de base".</param>
        /// <returns></returns>
        public static bool Contains(this string source, string toCheck, bool ignoreCaseAndDiacritics)
        {
            if (ignoreCaseAndDiacritics)
                return source.Contains(toCheck, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace);
            else
                return source.Contains(toCheck);
        }
    }
}
